import { CSSProperties, camelize } from 'vue'
import { AlignmentType, UnderlineType, WidthType } from 'docx'
import { parseStringStyle } from '@vue/shared'
import {
  convertFontSize,
  convertPtToTwips,
  convertToNumber,
  isHexColor,
  pxToPt,
  rgbToHexColor
} from '../utils'
import { isPercentValue } from '../../numbers'

const styleTransformMap = {
  color: {
    property: 'color',
    handler: (value) => {
      if (isHexColor(value)) return value

      //  dom 元素会将 hex 转为 rgb 需要手动转回来
      return rgbToHexColor(value)
    }
  },
  /**
   * @default
   *
   *  默认字号小四
   */
  fontSize: {
    property: 'size',
    handler: (value) => {
      return convertFontSize(value || 12)
    }
  },
  textDecoration: {
    property: 'underline',
    handler: (value, style) => {
      return {
        type: UnderlineType.SINGLE,
        color: style.color ? rgbToHexColor(style.color) : undefined
      }
    }
  },
  textIndent: {
    /**
     * @default
     * 默认处理 pt
     * Twips 单位
     */
    property: 'indent',
    handler: (value, style) => {
      const fontSize = convertToNumber(style.fontSize)
      const em = convertToNumber(value)
      return {
        firstLine: convertPtToTwips(fontSize * em)
      }
    }
  },
  textAlign: {
    property: 'alignment',
    handler: (value) => {
      if (value === 'center') {
        return AlignmentType.CENTER
      }

      if (value === 'right') {
        return AlignmentType.RIGHT
      }
      return AlignmentType.LEFT
    }
  },
  fontWeight: {
    property: 'bold',
    handler: (value) => !!value
  },
  fontFamily: {
    property: 'font',
    handler: (value) => {
      return value
    }
  },
  lineHeight: {
    // convertFontSize
    property: 'lineSpacing',
    handler: (value) => {
      if (!value) return

      return convertToNumber(value) * 20
    }
  }
}

export function cssStylesToAttrs(style: CSSProperties): any {
  const attrs: any = {}
  Object.keys(style).forEach((key) => {
    const _key = camelize(key)

    const value = style[key]
    const config = styleTransformMap[_key]

    if (config) {
      attrs[config.property] = config.handler(value, style)
      return
    }

    attrs[_key] = value
  })

  return attrs
}

const tagTrasnformMap = {
  // 斜线
  em: {
    property: 'italics',
    handler: () => {
      return true
    }
  },
  strong: {
    property: 'bold',
    handler: () => {
      return true
    }
  }
}

export function tagsToAttrs(tags: string[]) {
  const attrs: any = {}

  tags.forEach((tag) => {
    const config = tagTrasnformMap[tag]
    if (!config) return

    attrs[config.property] = config.handler()
  })

  return attrs
}

/**
 * 转换 table cell 样式
 */
export function getTableCellAttrs(cell: Element) {
  const rowSpan = Number(cell.getAttribute('rowSpan') || 1)
  const columnSpan = Number(cell.getAttribute('colSpan') || 1)
  const cellWidth = cell.getAttribute('width')
  const styles = getInlineStyles(cell.getAttribute('style') || '')

  const tableCellOptions: Record<string, any> = {
    rowSpan,
    columnSpan
  }
  const width = styles.width || cellWidth
  if (width) {
    try {
      let size: any = width

      if (isPercentValue(size)) {
        size = cellWidth
      } else {
        size = pxToPt(size)
      }

      tableCellOptions.width = {
        size,
        type: WidthType.DXA
      }
    } catch (error) {
      console.error(error)
    }
  }

  return tableCellOptions
}

// 行内样式转对象
export function getInlineStyles(element: any) {
  const styles: CSSProperties = {}

  const cahceStyles = parseStringStyle(element?.style?.cssText || '')

  Object.keys(cahceStyles).forEach((key) => {
    styles[camelize(key)] = cahceStyles[key]
  })

  return styles
}
